/*******************************************************************************
 * Copyright 2013 Comcast Cable Communications Management, LLC
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.comcast.freeflow.core;

import java.util.HashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import com.comcast.freeflow.helpers.DefaultSectionAdapter;
import com.comcast.freeflow.layouts.FreeFlowLayout;
import com.comcast.freeflow.layouts.VLayout;
import com.comcast.freeflow.teststub.MainActivity;

import android.app.Activity;
import android.graphics.Rect;
import android.test.ActivityInstrumentationTestCase2;
import android.view.ViewTreeObserver.OnPreDrawListener;

public class FreeFlowContainerTest extends ActivityInstrumentationTestCase2<MainActivity> {
	
	Activity main ;
	
	public FreeFlowContainerTest() {
		super(MainActivity.class);
		
	}

	protected void setUp() throws Exception {
		super.setUp();
		main = getActivity();
	}
	
	protected void tearDown() throws Exception {
		super.tearDown();
	}
	
	/**
	 * Tests that changing an attached layout cannot change 
	 * the internal map of the item proxies insode a container
	 * 
	 * @throws InterruptedException
	 */
	public void testSourceCannotModifyFreeFlowContainerReferences() throws InterruptedException{
		final CountDownLatch lock = new CountDownLatch(1);
		main.runOnUiThread(new Runnable() {
			
			@Override
			public void run() {
				
				final FreeFlowContainer container = new FreeFlowContainer(main);
							
				
				final VLayout vLayout = new VLayout();
				vLayout.setLayoutParams(new VLayout.LayoutParams(300, 200, 10));
				container.setLayout(vLayout);
				
				final DefaultSectionAdapter adapter = new DefaultSectionAdapter(main, 1, 2);
				container.setAdapter(adapter);
				
				
				main.setContentView(container);	
				
				container.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
					@Override
					public boolean onPreDraw() {
						
						int frameCount = container.getFrames().size();
						adapter.setData(5, 10);
						
						// setItems will force new frames to be generated, but not set 
						vLayout.setAdapter(adapter); 
						vLayout.prepareLayout() ;
						
						//assertEquals("Layout frames did not generate as expected", 5*(10+1), vLayout.getAllProxies().size());
						assertEquals("FreeFlowContainer frames changed unexpectedly with data", frameCount, container.getFrames().size());
						
						lock.countDown();
						return false;
					}
				});
			}
		});
		lock.await(5000, TimeUnit.MILLISECONDS);
	}
	
	/**
	 * Tests that all items are generated by the time predraw kicks in
	 * 
	 * @throws InterruptedException
	 */
	public void testAllViewsAreGeneratedByFirstLayout() throws InterruptedException{
		final CountDownLatch lock = new CountDownLatch(1);
		main.runOnUiThread(new Runnable() {
			
			@Override
			public void run() {
				
				final FreeFlowContainer container = new FreeFlowContainer(main);
				
				DefaultSectionAdapter adapter = new DefaultSectionAdapter(main, 1, 2);
				container.setAdapter(adapter);
				
				VLayout vLayout = new VLayout();
				vLayout.setLayoutParams(new VLayout.LayoutParams(300, 200, 10));
				container.setLayout(vLayout);
				
				container.addFreeFlowEventListener( new FreeFlowEventListener() {
					
					@Override
					public void onLayoutChanging(FreeFlowLayout oldLayout,
							FreeFlowLayout newLayout) {
					}
					
					@Override
					public void layoutComputed() {
					}
					
					@Override
					public void layoutComplete(boolean areTransitionAnimationsPlaying) {
						assertEquals("Correct number of children were not created", 3, container.getChildCount());
					}
					
					@Override
					public void dataChanged() {
					}
					
					@Override
					public void animationsStarted() {
					}
					
					@Override
					public void layoutChangeAnimationsComplete() {
					}
				} );
				
				main.setContentView(container);	
				
				
			}
		});
		lock.await(5000, TimeUnit.MILLISECONDS);
		
	}
	
	/**
	 * Tests if a view is within the viewport and is moved,
	 */
	public void testViewChangesWhenViewMovesWithinViewport(){
		
		HashMap<Object, FreeFlowItem> oldMap = new HashMap<Object, FreeFlowItem>();
		HashMap<Object, FreeFlowItem> newMap = new HashMap<Object, FreeFlowItem>();
		
		
		String one = "one";
		FreeFlowItem proxy = new FreeFlowItem();
		proxy.data = one;
		proxy.frame = new Rect(0,0, 20, 20);
		oldMap.put(one, proxy);
		
		FreeFlowItem proxy2 = new FreeFlowItem();
		proxy.data = one;
		proxy.frame =  new Rect(20,20,20+40,20+40);
		newMap.put(one, proxy2);
		
		FreeFlowContainer container = new FreeFlowContainer(getActivity());
		LayoutChangeset changes = container.getViewChanges(oldMap, newMap);
		
		assertTrue(changes.getMoved().size() == 1);
		assertTrue(changes.getAdded().size() == 0);
		assertTrue(changes.getRemoved().size() == 0);
	}
	
	
//	public void testAsync(){
//		FreeFlowContainer c = new FreeFlowContainer(getActivity());
//		c.setLayoutParams(new LayoutParams(400,400));
//		
//	}
	
	
}
